﻿using AccessibilityTools.DB;
using Newtonsoft.Json;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TianYi.Bll;
using TianYi.Helper;

namespace TianYi
{
    public class TaskAction
    {
        #region 声明委托
        public delegate void AddLogHandler(string source, string log);
        public static event AddLogHandler AddLogEventHandler;
        #endregion

        #region  声明数据库
        ErrorInfoLogic ErrorInfoLogic = new ErrorInfoLogic();
        PressureValueInfoLogic PressureValueInfoLogic = new PressureValueInfoLogic();
        ProductionDetalisLogic ProductionDetalisLogic = new ProductionDetalisLogic();
        #endregion

        #region 声明变量
        PlcToPc _plcToPc;
        PcToPlc _pcToPlc;
        short _lastTcStart, _lastTcStartStation1, _lastTcStartStation2, _lastTcStartPressure;//复位信号
        bool _tick10;//心跳op10....
        #endregion

        #region 开启心跳和扫码业务线程
        /// <summary>
        /// 心跳信号开启，扫码信号开启，装箱信号开启
        /// </summary>
        public void StartAction(PlcController plc)
        {
            this._plcToPc = new PlcToPc(plc);
            this._pcToPlc = new PcToPlc(plc);

            Thread.Sleep(1000);//需要先等数据库先连接成功，有可能会报错

            Task.Run(async () =>
            {
                await HeartbeatAction(plc); //心跳
            });

            Task.Run(async () =>
            {
                await Monitor(plc); //plc报警信息
            });
            //开启循环接收压力值
            Task.Run(async () =>
            {
                await GetPressureValue(plc);
            });
            Task.Factory.StartNew(() =>
            {
                BusinessEvent(plc);//扫码业务不能使用异步方法
            }
            , TaskCreationOptions.LongRunning);

        }
        #endregion


        #region 开启业务
        /// <summary>
        /// 循环接收每个工站业务信息
        /// </summary>
        /// <returns></returns>

        private void BusinessEvent(PlcController plc)
        {
            while (plc.IsConnected)
            {
                #region 总站工作
                int uploadStart = _plcToPc.UploadStar;//循环接收总站请求信号DB1000.DBW2

                if (uploadStart == 100 && uploadStart != _lastTcStart)
                {

                    AddLogEventHandler?.Invoke("接收到总请求业务", "总数据");
                    LogHelper.WriteInfo("业务,已接收到总业务信号");//需要给plc读取条码清零信号吗
                    //开始接收数据
                  
                    ProductionDetailsInfo productionDetailsInstance = new ProductionDetailsInfo()
                    {
                        ProductTypes = _plcToPc.Sn_ChannelOP10A(),  //sn
                        Production_Length = _plcToPc.ProductionLength(), //长度
                        Large_Outer_Diameter = _plcToPc.LargOutDiamter(),
                        Small_Outer_Diameter = _plcToPc.SmallOutDiamter(),
                        Bottom_Cover_Value = _plcToPc.BottomCoverValue(),
                        Production_Height = _plcToPc.ProductionHeight(),
                        Displacement_Value= _plcToPc.DisplacementValue(),
                        Pressure_Limmit_Value = _plcToPc.PressureLimitValue(),
                        CreationTime = DateTime.Now,
                        Qr_Code=_plcToPc.QrCode()
                    };
                    int count = ProductionDetalisLogic.Add(productionDetailsInstance);
                    if (count>0)
                    {
                        AddLogEventHandler?.Invoke("总数据写入成功", "生产表");
                        LogHelper.WriteInfo("业务,总数据写入成功");
                    }
                    else
                    {
                        AddLogEventHandler?.Invoke("总数据写入失败", "生产表");
                        LogHelper.WriteInfo("业务,总数据写入失败");
                    }
                    _pcToPlc.UploadDoneSign(100);  //DB1000.DBW4反馈总站完成信号 4,8,12分别是
                    AddLogEventHandler?.Invoke("总站工作结束", "已经向PLC发送完成信号");
                    _lastTcStart = (short)uploadStart;

                }
                //当plc将上传信号改变为零时候复位_lastTcOP10left，等待下次为1时候进入
                else if (uploadStart == 0)
                {
                    _lastTcStart = 0;
                }
                #endregion

                #region 第一站开始工作
                int uploadStartStation1 = _plcToPc.UploadStartStation1;//循环接收到扫码请求

                if (uploadStartStation1 == 100 && uploadStartStation1 != _lastTcStartStation1)
                {
                    AddLogEventHandler?.Invoke("接收到工站一请求业务", "工站一");
                    LogHelper.WriteInfo("业务,已接收到工站一上传信号");
                    //开始接收数据
                    ProductionDetailsInfo productionDetailsInstance = new ProductionDetailsInfo()
                    {
                        ProductTypes = _plcToPc.Sn_ChannelOP10A(),  //sn
                        Production_Length = _plcToPc.ProductionLength(),
                        Large_Outer_Diameter = _plcToPc.LargOutDiamter(),
                        Small_Outer_Diameter= _plcToPc.SmallOutDiamter(),
                        CreationTime = DateTime.Now

                    };
                   int count= ProductionDetalisLogic.Add(productionDetailsInstance);
                    if (count>0)
                    {
                        AddLogEventHandler?.Invoke("工站一数据写入成功", "工站一");
                        LogHelper.WriteInfo("业务,总数据写入成功");
                    }
                    else
                    {
                        AddLogEventHandler?.Invoke("工站一数据写入失败", "工站一");
                        LogHelper.WriteInfo("业务,总数据写入失败");
                    }
                    _pcToPlc.UploadDoneSignStation1(100);
                    AddLogEventHandler?.Invoke("第一站工作结束", "已经向PLC发送完成信号");
                    _lastTcStartStation1 = (short)uploadStartStation1;

                }
                //当plc将上传信号改变为零时候复位_lastTcOP10left，等待下次为1时候进入
                else if (uploadStartStation1 == 0)
                {
                    _lastTcStartStation1 = 0;
                }
                #endregion

                #region 第二站开始工作
                int uploadStartStation2 = _plcToPc.UploadStartStation2;//循环接收到工站二请求

                if (uploadStartStation2 == 100 && uploadStartStation2 != _lastTcStartStation2)
                {
                    AddLogEventHandler?.Invoke("接收到工站二请求业务", "工站二");
                    LogHelper.WriteInfo("业务,已接收到工站二上传信号");

                    //第二站
                    ProductionDetailsInfo productionDetailsInstance = new ProductionDetailsInfo()
                    {

                       Bottom_Cover_Value=_plcToPc.BottomCoverValue(),
                       Production_Height= _plcToPc.ProductionHeight(),
                       Displacement_Value= _plcToPc.DisplacementValue(),
                       Pressure_Limmit_Value = _plcToPc.PressureLimitValue(),
                       CreationTime = DateTime.Now,
                       Qr_Code=_plcToPc.QrCode()
                    };
                   int count= ProductionDetalisLogic.Add(productionDetailsInstance);
                    if (count>0)
                    {
                        AddLogEventHandler?.Invoke("工站二更新数据成功", "工站二");
                        LogHelper.WriteInfo("业务,工站二更新数据成功");
                    }
                    else
                    {
                        AddLogEventHandler?.Invoke("工站二更新数据失败", "工站二");
                        LogHelper.WriteInfo("业务,工站二更新数据失败");
                    }

                  
                    _pcToPlc.UploadDoneSignStation2(100);
                    AddLogEventHandler?.Invoke("第二站工作结束", "已经向PLC发送完成信号");

                    _lastTcStartStation2 = (short)uploadStartStation2;

                }
                //当plc将上传信号改变为零时候复位_lastTcOP10left，等待下次为1时候进入
                else if (uploadStartStation2 == 0)
                {
                    _lastTcStartStation2 = 0;
                }
                #endregion

                Task.Delay(50);
            }
        }
        #endregion

        #region 开启心跳
        /// <summary>
        /// 执行心跳看哪个plc传入,需要判定是那个plc对象
        /// </summary>
        /// <returns></returns>
        private async Task HeartbeatAction(PlcController plc)
        {

            LogHelper.WriteInfo("程序已开始发送心跳");
            AddLogEventHandler?.Invoke("心跳已开启", "心跳");
            _tick10 = true;

            while (plc.IsConnected)
            {

                _pcToPlc.WatchDog10 = Convert.ToInt16(_tick10);//发送trueDB1000.DBW0
                await Task.Delay(200);
                _tick10 = !_tick10;//负责显示通断

            }
        }
        #endregion

        #region 循环接收压力值
        /// <summary>
        /// 
        /// </summary>
        /// <param name="plc">传入的plc</param>
        /// <param name="sn">当前读到的sn码</param>
        /// <param name="rework">是否返工说明</param>
        private async Task GetPressureValue(PlcController plc)
        {
            List<AxisData> listRecord = new List<AxisData>();
            string content = "";
            LogHelper.WriteInfo("业务,开启压力值检测");
            AddLogEventHandler?.Invoke("实时压力检测线程已开启", "压力值数据");
            while (plc.IsConnected)
            {
                //接收压力完成信号
                int readDoneWork = _plcToPc.UploadDonePressureSign();
                int uploadStartPressure = readDoneWork;
                if (readDoneWork == 1)
                {

                    AxisData ins = new AxisData()
                    {
                        Axis_Y = _plcToPc.PressureValue().ToString(),//实时接收压力数据
                    };
                    listRecord.Add(ins);
                   

                }
                else if (readDoneWork == 2 && uploadStartPressure!= _lastTcStartPressure)

                {
                    foreach (var item in listRecord)
                    {
                        content += item.Axis_Y + ",";
                    }
                    //更新压力数据库
                    PressureValueInfo pressureValueInstance = new PressureValueInfo()
                    {
                        PressureValue = content,
                        CreationTime = DateTime.Now
                    };
                   int count= PressureValueInfoLogic.Add(pressureValueInstance);
                    if (count>0)
                    {
                        LogHelper.WriteInfo("业务,压力值检测结束");
                        AddLogEventHandler?.Invoke("压力值检测结束", "已写入压力表");
                    }
                    else
                    {
                        LogHelper.WriteInfo("业务,压力值检测结束，写入数据库失败");
                        AddLogEventHandler?.Invoke("压力值检测结束", "写入压力表数据库失败");
                    }
                    _lastTcStartPressure = (short)readDoneWork;


                }
                //当plc将上传信号改变为零时候复位_lastTcOP10left，等待下次为1时候进入
                else if (readDoneWork == 0)
                {
                    _lastTcStartPressure = 0;
                }
                await Task.Delay(10);

            }
        }
        #endregion

        #region 监控报警信息
        /// <summary>
        /// 监控报警
        /// </summary>
        /// <returns></returns>
        private async Task Monitor(PlcController plc)
        {

            while (plc.IsConnected)
            {
                ////监控plc报警 如果与最近一条报警相同 则不插入新数据
            }
        }
        #endregion


    }
    public class AxisData
    {

        public string Axis_Y;
    }
}
